
#include "imglib/winbmp.h"

namespace img {

/*
void BlendBitmap(HDC hDC, int xd, int yd, int wd, int hd, int xs, int ys,	int ws,	int hs,	const bitmap & bmp, COLORREF foreground, COLORREF background, unsigned char alpha)
{
	bitmap_info info;
	memset(&info, 0, sizeof(bitmap_info));

	BITMAPINFOHEADER & header = info.bmiHeader;
										  
	int w = bmp.width(), h = bmp.height();

	if (bmp.order() == bottom_up) {
		ys = h - hs - ys;
	} else {
		h = - h;
	}

	header.biSize			= sizeof(BITMAPINFOHEADER); 
	header.biWidth			= w; 
	header.biHeight			= h; 
	header.biPlanes			= 1; 
	header.biBitCount		= 1; 
	header.biCompression	= BI_RGB;
	
	RGBQUAD & fg = info.bmiColors[1];

	fg.rgbBlue	= GetBValue(foreground);
	fg.rgbGreen	= GetGValue(foreground);
	fg.rgbRed	= GetRValue(foreground);

	RGBQUAD & bg = info.bmiColors[0];

	bg.rgbBlue	= GetBValue(background);
	bg.rgbGreen	= GetGValue(background);
	bg.rgbRed	= GetRValue(background);

	BITMAPINFO * pinfo = reinterpret_cast<BITMAPINFO *>(&info);

	BLENDFUNCTION blend;
	blend.BlendOp = AC_SRC_OVER;
	blend.BlendFlags = 0;
	blend.SourceConstantAlpha = alpha;
	blend.AlphaFormat = 0;

	AlphaDIBBlend(hDC, xd, yd, wd, hd, bmp.data(), pinfo, DIB_RGB_COLORS, 
		xs, ys, ws, hs, blend);
}
*/

void BlendBitmap(HDC hDC, int xd, int yd, int wd, int hd, int xs, int ys,	int ws,	int hs,	const bitmap & bmp, COLORREF foreground, COLORREF background, unsigned char alpha)
{
	BLENDFUNCTION blend;
	blend.BlendOp = AC_SRC_OVER;
	blend.BlendFlags = 0;
	blend.SourceConstantAlpha = alpha;
	blend.AlphaFormat = 0;

	HDC tmpDC = CreateCompatibleDC(hDC);

	HBITMAP tmpBmp = CreateCompatibleBitmap(hDC, ws, hs);
	HGDIOBJ oldBmp = SelectObject(tmpDC, tmpBmp);

	DrawBitmap(tmpDC, 0, 0, ws, hs, xs, ys, bmp, foreground, background);
	BOOL res = AlphaBlend(hDC, xd, yd, wd, hd, tmpDC, 0, 0, ws, hs, blend);
	assert(res);

	SelectObject(tmpDC, oldBmp);
	DeleteObject(tmpBmp);
	DeleteDC(tmpDC);
}

BitmapBlender::BitmapBlender()
	: _hbmp(0), _hdc(0), _dim(0, 0)
{

}

BitmapBlender::~BitmapBlender()
{
	if (_hdc != 0)
		DeleteDC(_hdc);
	if (_hbmp != 0)
		DeleteObject(_hbmp);
}

void BitmapBlender::operator () (HDC hDC, int xd, int yd, int wd, int hd, int xs, int ys, int ws, int hs, 
	const bitmap & bmp, COLORREF foreground, COLORREF background, unsigned char alpha)
{
	if (_hdc == 0) {
		_hdc = CreateCompatibleDC(hDC);
		assert(_hdc != 0);
	}

	if (_hbmp == 0 || _dim < bmp.dim()) {
		assert(_hdc != 0);
		if (_hbmp != 0) {
			SelectObject(_hdc, _hold);
			DeleteObject(_hbmp);
		}
		_dim = bmp.dim();
		_hbmp = CreateCompatibleBitmap(hDC, _dim.sx, _dim.sy);
		assert(_hbmp != 0);
		_hold = (HBITMAP) SelectObject(_hdc, _hbmp);
	}

	BLENDFUNCTION blend;
	blend.BlendOp = AC_SRC_OVER;
	blend.BlendFlags = 0;
	blend.SourceConstantAlpha = alpha;
	blend.AlphaFormat = 0;

//	HDC tmpDC = CreateCompatibleDC(hDC);

//	HBITMAP htemp = CreateCompatibleBitmap(hDC, ws, hs);

//	HBITMAP tmpBmp = _htemp;

//	HGDIOBJ oldBmp = SelectObject(tmpDC, tmpBmp);

	DrawBitmap(_hdc, xs, ys, ws, hs, xs, ys, bmp, foreground, background);
	BOOL res = AlphaBlend(hDC, xd, yd, wd, hd, _hdc, xs, ys, ws, hs, blend);
	assert(res);

//	SelectObject(tmpDC, oldBmp);
//	DeleteObject(htemp);
//	DeleteDC(tmpDC);
}


} // img
